new Handle:g_TelePlayer = INVALID_HANDLE
new Handle:g_TeleTeleTime = INVALID_HANDLE
new Handle:g_TeleWaitTime = INVALID_HANDLE
new Handle:g_TeleSaveTime = INVALID_HANDLE
new Handle:g_TeleNotice = INVALID_HANDLE
new Handle:g_TeleEffects = INVALID_HANDLE
new Handle:g_Ad = INVALID_HANDLE
new Handle:g_Info = INVALID_HANDLE
new m_iUserUsed[MAXPLAYERS+1] = {0, ...}
new m_iLastUsed[MAXPLAYERS+1] = {0, ...}
new Float:m_iPlayerCords[MAXPLAYERS+1][3]
new bool:m_iSaveDone[MAXPLAYERS+1] = true
new bool:m_iTeleDone[MAXPLAYERS+1] = true
new bool:IsRespawn[MAXPLAYERS+1] = false
new g_LightningSprite

public OnClientConnected(client)
{
	if (IsFakeClient(client))
		return

	if (GetConVarInt(g_Ad) == 1 && GetConVarInt(g_TelePlayer) == 1){
		timer1[client] = CreateTimer(30.0, DO_Tele_Advertise, client)
	}

	if (GetConVarInt(g_Info) == 1){
		new Float:DelayStart = GetConVarFloat(g_InfoDelay2)
		if (DelayStart > 0.0) {
			timer2[client] = CreateTimer(DelayStart, DO_InfoPlayer, client)
		}
	}

	m_iUserUsed[client] = 0
	m_iLastUsed[client] = 0
	m_iTeleDone[client] = true
	m_iSaveDone[client] = true 
	AGoto[client] = true
	IsSpec[client] = false
	IsRespawn[client] = false
}

public OnClientDisconnect(client)
{
	IsSpec[client] = false
	IsRespawn[client] = false
	if (timer1[client] != INVALID_HANDLE){
		KillTimer(timer1[client])
		timer1[client] = INVALID_HANDLE
	}
	if (timer2[client] != INVALID_HANDLE){
		KillTimer(timer2[client])
		timer2[client] = INVALID_HANDLE
	}
}

public Action:SaveClientLocation(client, args)
{
	if(GetConVarInt(g_TelePlayer) == 1)
	{
		if (IsPlayerAlive(client) && IsClientConnected(client) && m_iSaveDone[client] && m_iTeleDone[client])
		{
			new Float:i_mDelay = GetConVarFloat (g_TeleSaveTime)
			if (i_mDelay >=0.0)
			{
				m_iSaveDone[client] = false
				m_iTeleDone[client] = false
				CreateTimer(i_mDelay, PerformSave, client)

				if (GetConVarInt(g_TeleNotice) == 1 && GetConVarInt(g_TeleSaveTime) >= 3)
				{
					new savedelay = GetConVarInt(g_TeleSaveTime)
					PrintToChat(client,"\x01\x04[SM] %T", "Notice_Save_sec", LANG_SERVER, savedelay)
				}
				else if (GetConVarInt(g_TeleNotice) == 1)
				{
					PrintToChat(client,"\x01\x04[SM] %T", "Notice_Save", LANG_SERVER)
				}
			}
		}
		else
		{
			if (GetConVarInt(g_TeleNotice) == 1 && m_iSaveDone[client])
			{
				PrintToChat(client,"\x01\x04[SM] %T", "Notice_Dead", LANG_SERVER)
			}
		}
	}
	else
	{
		if (GetConVarInt(g_TeleNotice) == 1)
		{
			PrintToChat(client,"\x01\x04[SM] %T", "Notice_Disabled", LANG_SERVER)
		}
	}
	return Plugin_Handled
}

public Action:TeleClient(client, args)
{
	if(GetConVarInt(g_TelePlayer) == 1)
	{
		if (IsPlayerAlive(client) && IsClientConnected(client) && m_iTeleDone[client] && m_iSaveDone[client])
		{
			new curTime = GetTime()
			if ((curTime - m_iLastUsed[client]) < GetConVarFloat(g_TeleWaitTime))
			{
				if (GetConVarInt(g_TeleNotice) == 1)
				{
					new waitdelay = GetConVarInt(g_TeleWaitTime) - (curTime - m_iLastUsed[client])
					PrintToChat(client,"\x01\x04[SM] %T", "Notice_Teleport_Wait", LANG_SERVER, waitdelay)
				}
			}
			else
			{
				new Float:i_mTimer = GetConVarFloat(g_TeleTeleTime)
				if (i_mTimer>=1.0)
				{
					m_iTeleDone[client] = false
					m_iSaveDone[client] = false
					m_iLastUsed[client] = curTime
					CreateTimer(i_mTimer, PerformTele, client)
					if (GetConVarInt(g_TeleEffects) == 1){
						CreateParticle(PARTICLE, i_mTimer, client)
						
						new Float:vec[3]
						new Float:dir[3] = {0.0, 0.0, 0.0}
						GetClientAbsOrigin(client, vec)
						
						TE_SetupSparks(vec, dir, 5000, 1000)
						TE_SendToAll()
						
						EmitAmbientSound(SOUND_UP, vec, client, SNDLEVEL_NORMAL, _, _, _, _)
					}
					if (GetConVarInt(g_TeleNotice) == 1 && GetConVarInt(g_TeleTeleTime) >= 3)
					{
						new teledelay = GetConVarInt(g_TeleTeleTime)
						PrintToChat(client,"\x01\x04[SM] %T", "Notice_Teleport_sec", LANG_SERVER, teledelay)
					}
					else if (GetConVarInt(g_TeleNotice) == 1)
					{
						PrintToChat(client,"\x01\x04[SM] %T", "Notice_Teleport", LANG_SERVER)
					}
				}
			}
		}
		else
		{
			if (GetConVarInt(g_TeleNotice) == 1 && m_iTeleDone[client])
			{
				PrintToChat(client,"\x01\x04[SM] %T", "Notice_Dead", LANG_SERVER)
			}
		}
	}
	else
	{
		if (GetConVarInt(g_TeleNotice) == 1)
		{
			PrintToChat(client,"\x01\x04[SM] %T", "Notice_Disabled", LANG_SERVER)
		}
	}
	return Plugin_Handled
}

public Action:PerformTele(Handle:timer, any:client)
{
	if (m_iUserUsed[client] == 0){
		if (GetConVarInt(g_TeleNotice) == 1){
			PrintToChat(client,"\x01\x04[SM] %T", "Notice_DidNotSave", LANG_SERVER)
			m_iTeleDone[client] = true
			m_iSaveDone[client] = true
		}
		return Plugin_Handled
	}
	
	if (GetConVarInt(g_TeleEffects) == 1){
		CreateParticle(PARTICLE, 10.0, client)
		
		new color1[3] = {0, 0, 0}
		decl String:str_color[12]
		color1[0] = GetRandomInt(1, 255)
		color1[1] = GetRandomInt(1, 255)
		color1[2] = GetRandomInt(1, 255)
		Format(str_color, sizeof(str_color), "%d %d %d", color1[0], color1[1], color1[2])
		
		if (Debug)
			PrintToChat(client,"color is %s", str_color)
	
		CreateSpriteTrail(SPRITETRAIL, 20.0, str_color, "20", client)
		
		new Float:vec[3]
		GetClientAbsOrigin(client, vec)

		new color[4] = {255, 255, 255, 255}
		new Float:dir[3] = {0.0, 0.0, 0.0}

		new Float:startpos[3]
		startpos[0] = vec[0]
		startpos[1] = vec[1]
		startpos[2] = vec[2] + 1000
	
		EmitAmbientSound(SOUND_TELE, vec, client, SNDLEVEL_NORMAL)

		TE_SetupEnergySplash(vec, dir, false)
		TE_SendToAll()

		TE_SetupBeamPoints(startpos, vec, g_LightningSprite, 0, 0, 0, 5.0, 20.0, 10.0, 0, 1.0, color, 3)
		TE_SendToAll()
	}

	TeleportEntity(client, m_iPlayerCords[client],NULL_VECTOR,NULL_VECTOR)

	m_iTeleDone[client] = true
	m_iSaveDone[client] = true
	return Plugin_Handled
}

public Action:PerformSave(Handle:timer, any:client)
{
	if ((client <= 0) || !IsClientInGame(client)){
		return Plugin_Handled
	}

	m_iUserUsed[client] = 1
	GetClientAbsOrigin(client,m_iPlayerCords[client])
	if (GetConVarInt(g_TeleNotice) == 1)
	{
		PrintToChat(client,"\x01\x04[SM] %T", "Notice_SaveDone", LANG_SERVER)
	}
	m_iSaveDone[client] = true
	m_iTeleDone[client] = true
	return Plugin_Handled
}

public Action:DO_Tele_Advertise(Handle:timer, any:client)
{
	if (IsClientInGame(client)){
		PrintToChat(client,"\x01\x04[SM] %T", "Advertise", LANG_SERVER)
		timer1[client] = INVALID_HANDLE
	}
}

CheckTeleport(client)
{
	m_iTeleDone[client] = true
	m_iSaveDone[client] = true 
}

stock Handle:CreateParticle(String:type[], Float:time, entity, Float:xOffs=0.0, Float:yOffs=0.0, Float:zOffs=0.0)
{
	new particle = CreateEntityByName("info_particle_system")
	
	if (IsValidEdict(particle)) 
	{
		if (Debug)
			PrintToChat(entity, "particle valid")
		
		decl Float:pos[3]
		GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos)
		pos[0] += xOffs
		pos[1] += yOffs
		pos[2] += zOffs
		TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR)
		DispatchKeyValue(particle, "effect_name", type)
		SetVariantString("!activator")
		AcceptEntityInput(particle, "SetParent", entity, particle, 0)
		DispatchKeyValue(particle, "targetname", "present")
		DispatchSpawn(particle)
		ActivateEntity(particle)
		AcceptEntityInput(particle, "Start")
		return CreateTimer(time, DeleteParticle, particle)
	} 
	else 
	{
		LogError("Presents (CreateParticle): Could not create info_particle_system")
	}
	return INVALID_HANDLE
}

public Action:DeleteParticle(Handle:timer, any:particle)
{
	if (IsValidEdict(particle)) 
	{
		new String:classname[64]
		GetEdictClassname(particle, classname, sizeof(classname))

		if (StrEqual(classname, "info_particle_system", false)) 
		{
			RemoveEdict(particle)
			if (Debug)
				PrintToChatAll("particle removed")
		}
	}
}

stock Handle:CreateSpriteTrail(String:type[], Float:time, String:color[], String:lifetime[], entity, Float:xOffs=0.0, Float:yOffs=0.0, Float:zOffs=10.0)
{
	new SpriteTrail = CreateEntityByName("env_spritetrail")
	
	if (IsValidEdict(SpriteTrail)) 
	{
		if (Debug)
			PrintToChat(entity, "spritetrail valid")
		
		decl Float:pos[3]
		GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos)
		pos[0] += xOffs
		pos[1] += yOffs
		pos[2] += zOffs
		TeleportEntity(SpriteTrail, pos, NULL_VECTOR, NULL_VECTOR)
		DispatchKeyValue(SpriteTrail, "spritename", type)
		DispatchKeyValue(SpriteTrail, "renderamt", "255")
		DispatchKeyValue(SpriteTrail, "rendercolor", color)
		DispatchKeyValue(SpriteTrail, "rendermode", "5")
		DispatchKeyValue(SpriteTrail, "lifetime", lifetime)
		DispatchKeyValue(SpriteTrail, "startwidth", "100")
		DispatchKeyValue(SpriteTrail, "endwidth", "0.000004")
		SetVariantString("!activator")
		AcceptEntityInput(SpriteTrail, "SetParent", entity, SpriteTrail, 0)
		DispatchKeyValue(SpriteTrail, "targetname", "sprite_")
		DispatchSpawn(SpriteTrail)
		ActivateEntity(SpriteTrail)
		return CreateTimer(time, DeleteSpriteTrail, SpriteTrail)
	} 
	else 
	{
		LogError("Could not create env_spritetrail")
	}
	return INVALID_HANDLE
}

public Action:DeleteSpriteTrail(Handle:timer, any:SpriteTrail)
{
	if (IsValidEdict(SpriteTrail)) 
	{
		new String:classname[64]
		GetEdictClassname(SpriteTrail, classname, sizeof(classname))

		if (StrEqual(classname, "env_spritetrail", false)) 
		{
			RemoveEdict(SpriteTrail)
			if (Debug)
				PrintToChatAll("particle removed")
		}
	}
}